import { Helper } from "../tool/helper";
import { TransformNode } from "@babylonjs/core/Meshes/transformNode";
import { AbstractMesh } from "@babylonjs/core/Meshes/abstractMesh";
import { AssetContainer, InstantiatedEntries } from "@babylonjs/core/assetContainer";
import { Stage } from '../base/stage';


class SkinnedClone {

    private _instanceCount = 0;
    private _url: string;
    private _stage: Stage;

    public readonly assetContainer: AssetContainer;

    constructor(url: string, stage: Stage) {
        this._url = url;
        this._stage = stage;
        this.assetContainer = this.initializeAssetContainer();
    }

    public get url(): string { return this._url; }

    public get instance(): InstantiatedEntries {
        this._instanceCount++;
        const ie = this.assetContainer.instantiateModelsToScene((s) => { return s + this._instanceCount }, true, { doNotInstantiate: false });
        ie.rootNodes.forEach(n => {
            Helper.getChildMeshes(n as TransformNode).forEach(m => {
                m.isVisible = true;
                m.isPickable = false;
                if (m.skeleton) m.skeleton.useTextureToStoreBoneMatrices = false;
            });
        });
        return ie;
    }

    private initializeAssetContainer(): AssetContainer {
        const loader = this._stage.loader(this._stage.mainScene);
        const mt = loader.getMeshTaskInfo(this._url)!;
        const animationGroups = mt.loadedAnimationGroups!;
        animationGroups.forEach(ag => ag.stop());
        const meshes: AbstractMesh[] = mt.loadedMeshes!;
        meshes.forEach(m => {
            if (m.skeleton) m.skeleton.useTextureToStoreBoneMatrices = false;
            m.isVisible = false;
        });

        const ac = new AssetContainer(this._stage.mainScene);
        ac.animationGroups = animationGroups;
        ac.meshes = meshes;
        ac.transformNodes = mt.loadedTransformNodes!;
        ac.skeletons = mt.loadedSkeletons!;
        return ac;
    }

}


export { SkinnedClone };